package com.zyl.lock;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author zhaoyl
 * @date 2024/5/20 22:12
 * @description 说明
 * 测试 Spinlock
 *
 * 乐观锁/悲观锁
 * 乐观锁与悲观锁不是指具体的什么类型的锁，而是指看待并发同步的角度。
 * 悲观锁认为对于同一个数据的并发操作，一定是会发生修改的，哪怕没有修改，也会认为修改。因此对于同一个数据的并发操作，悲观锁采取加锁的形式。悲观的认为，不加锁的并发操作一定会出问题。
 * 乐观锁则认为对于同一个数据的并发操作，是不会发生修改的。在更新数据的时候，会采用尝试更新，不断重新的方式更新数据。乐观的认为，不加锁的并发操作是没有事情的。
 *
 * 从上面的描述我们可以看出，悲观锁适合写操作非常多的场景，乐观锁适合读操作非常多的场景，不加锁会带来大量的性能提升。
 * 悲观锁在Java中的使用，就是利用各种锁。
 * 乐观锁在Java中的使用，是无锁编程，常常采用的是CAS算法，典型的例子就是原子类，通过CAS自旋实现原子操作的更新。
 */
public class SpinlockTest {
    public static void main(String[] args) {
//        ReentrantLock reentrantLock = new ReentrantLock();
//        reentrantLock.lock();
//        reentrantLock.unlock();
        //底层使用自旋锁CAS
        SpinlockDemo lock = new SpinlockDemo();//自定义实现

        new Thread(()->{
            lock.mylock();
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                lock.myUnlock();
            }

        },"线程T1").start();

        //延迟
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

      //线程T1 解锁后 线程T2 才能加锁成功
        new Thread(()->{
            lock.mylock();
            try {
                TimeUnit.SECONDS.sleep(4);
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                lock.myUnlock();
            }
        },"线程T2").start();
    }
}
   /*     加锁-线程T1==>mylock
        线程T1加锁OK
        加锁-线程T2==>mylock
        解锁-线程T1==>myUnlock
        线程T1解锁OK
        线程T2加锁OK
        解锁-线程T2==>myUnlock
        线程T2解锁OK*/